var express = require('express');
var router = express.Router();
var multiparty = require('multiparty');
var { userModel } = require('../model/model.js');
var jwt = require('jsonwebtoken');
const { accessToken, refreshToken, secret } = require('../utils/token.js');
const { randomCode, sendCode } = require('../utils/sendCode.js');

const NodeCache = require("node-cache");
const myCache = new NodeCache();

const bcryptjs = require('bcryptjs'); //密码加密1


//  在这里添加与单点登录相关的路由和中间件
router.use('/sso', (req, res, next) => {
    let refreshToken = req.headers.authorization?.split(' ')[1];
    if (!refreshToken) {
        refreshToken = req.cookies.sso_token;
    }
    if (refreshToken) {
        try {
            const decoded = jwt.verify(refreshToken, 'secretKey');
            req.user = decoded;
            next();
        } catch (error) {
            res.status(401).send('Invalid token');
        }
    } else {
        res.status(401).send('No token provided');
    }
});


router.post('/addUser', async (req, res) => {
    let body = req.body;
    await userModel.create(body)
    res.send({ message: "user added" })
})


//发送验证码1
router.post("/getCode", async (req, res) => {
    let { phone } = req.body;
    let code = randomCode(4); //生成4位数字随机验证码

    myCache.set("phonecodes", code, 300); // 缓存5分钟

    sendCode(phone, code, function (success) {
        if (success) {
            res.send({
                code: 200,
                msg: "验证码发送成功",
                data: code,
                time: Date.now(),
            });
        } else {
            res.send("短信验证码发送失败");
        }
    });
});


// 验证验证码的有效期
function isCodeValid(creationTime) {
    //creationTime是在前段发送验证码的时候生成的时间戳
    const currentTime = Date.now(); //是在点击修改提交后会触发当前函数生成时间戳
    const expirationTime = 1 * 600 * 1000; // 1分钟的毫秒数
    return currentTime - creationTime <= expirationTime;
}

router.post('/phoneLogin', async (req, res) => {
    let { phone, code, time } = req.body;
    console.log(phone, code, time);
    let phonecode = myCache.get("phonecodes"); 
    if (phonecode == code) {
        let user = await userModel.findOne({ phone: phone });

        if (user && isCodeValid(time)) {
            res.send({
                code: 200,
                msg: "登录成功",
                user,
                accessToken: accessToken({ phone: phone }),
                refreshToken: refreshToken({ phone: phone })
            });
        } else if (user && !isCodeValid(time)) {
            res.send({
                code: 401,
                msg: "验证码已过期",
            });
        } else {
            res.send({
                code: 402,
                msg: "该手机号未注册,请输入密码进行注册",
            });
        }

    } else {
        res.send({
            code: 403,
            msg: "验证码不匹配",
        });
    }
})

router.post('/submit', async (req, res) => {
    let { phone, password, img, username, name } = req.body;
    console.log(phone, password, img, username, name);
    try {
        const hashedPassword = await bcryptjs.hash(password, 10)
        await userModel.create({ phone, password: hashedPassword, img, username, name })
        res.send({
            code: 200,
            msg: "注册成功"
        })
    } catch (error) {
        console.log(error)
        res.send({
            code: 401,
            msg: "注册失败"
        })
    }

})

router.post('/getList', async (req, res) => {
    res.send({ message: 'getList' })
})


// 验证长token是否有效，刷新短token
// 这里要注意，在刷新短token的时候回也返回新的长token，延续长token，
// 这样活跃用户在持续操作过程中不会被迫退出登录。长时间无操作的非活
// 跃用户长token过期重新登录
//判断长token是否有效
router.get("/refresh", async (req, res) => {
    //获取请求头中携带的长token
    let r_tk = req.headers.refreshtoken;
    console.log(r_tk, '长token');
    let phone = myCache.get("phone");

    //解析token
    jwt.verify(r_tk, secret, (err, decode) => {
        // 验证长token是否有效
        if (err) {
            //如果长token失效则返回401 前段回直接跳转会登录页面
            res.send({
                code: 401,
                msg: "token已过期，请重新登录",
            });
        } else {
            //如果长token有效则刷新两个token的保存时长
            res.send({
                code: 200,
                msg: "token刷新成功",
                accessToken: accessToken({ phone: phone }), //里面的对象是携带的用户信息，是用来生成token的
                refreshToken: refreshToken({ phone: phone }),
            });
        }
    });
});


router.post('/passwordLogin', async (req, res) => {
    try {
        let { phone, password } = req.body;
        let result = await userModel.findOne({ phone });
        if (result) {
            const vaildPassword = await bcryptjs.compare(password, result.password)
            if (vaildPassword) {
                console.log(res.getHeaders(), 1111)
                // res.cookie('sso_token', token, {
                //     httpOnly: false,
                //     maxAge: 3600000,
                //     path: '/',
                //   });
                res.send({
                    code: 200,
                    msg: '登录成功',
                    user: result,
                    accessToken: accessToken({ phone: phone }),
                    refreshToken: refreshToken({ phone: phone })
                })
            } else {
                res.send({
                    code: 400,
                    msg: '密码错误'
                })
            }
        } else {
            res.send({
                code: 400,
                msg: '该手机号未注册'
            })
        }
    } catch {

    }

})

const tencentcloud = require("tencentcloud-sdk-nodejs-iai")
//人脸识别登录
router.post('/faceLogin', async (req, res) => {
    //获取前端传来的base64
    let b64 = req.body.b64
    const IaiClient = tencentcloud.iai.v20200303.Client;
    try {
        const clientConfig = {
            credential: {
                //自己的腾讯secretId
                secretId: "AKIDRzTtR2c6X2ecmv2FQWhvgNzdO4uqBVls",
                //自己的腾讯密匙
                secretKey: "ELMOKLJKH8oGWcYHpCTfnu582obDj9Sj",
            },
            region: "ap-beijing",  //地域参数（华北地区北京）
            profile: {
                httpProfile: {
                    endpoint: "iai.tencentcloudapi.com",
                },
            },
        };
        const client = new IaiClient(clientConfig);
        const params1 = {
            "Image": b64,
            "FaceModelVersion": "3.0" //人脸识别所用的算法模型版本
        }
        // DetectLiveFaceAccurate 准确检测活体人脸的需求
        client.DetectLiveFaceAccurate(params1).then(
            async (data) => {
                if (data.Score > 87) {
                    const params = {
                        "GroupIds": [  //你创建的人员库ID
                            "123456"
                        ],
                        "Image": b64,  //图片的base64格式编码
                        "NeedPersonInfo": 1,  //是否返回人员具体信息。0 为关闭，1 为开启。默认为 0。
                        "QualityControl": 0,  //图片质量控制。 0: 不进行控制； 1:较低的质量要求 
                        "FaceMatchThreshold": 90,  //人脸对比度设置为大于90才可
                    };
                    let doc = await client.SearchFaces(params) // doc为人脸识别后的返回信息
                    if (doc.Results[0].Candidates.length != 0) {  //表示当前人脸库有该人员
                        let personName = doc.Results[0].Candidates[0].PersonName  //拿到该人员的名称
                        console.log(personName, 'personNume');
                        let user = await userModel.find({ username: personName })
                        console.log(user[0].phone, 'user');
                        if (user.length != 0) {
                            res.send({
                                code: 200,
                                msg: "登录成功！",
                                accessToken: accessToken({ phone: user[0].phone }),
                                refreshToken: refreshToken({ phone: user[0].phone }),
                                user: user[0],
                            })
                        }
                    } else {
                        res.send({
                            code: 401,
                            msg: '人脸库无此人！'
                        })
                        return false
                    }

                } else {
                    res.send({
                        code: 401,
                        msg: '请使用活物进行面部检测    '
                    })
                }
            },
            (err) => {
                console.error("error", err);
            }
        );
    } catch (err) {
        console.log(err);
    }

})

//面部认证
router.post('/bindFace', async (req, res) => {
    //获取前端传来的base64
    let b64 = req.body.b64
    let item = req.body.item
    let user = await userModel.findOne({ username: item.username })

    const IaiClient = tencentcloud.iai.v20200303.Client;


    const clientConfig = {
        credential: {
            secretId: "AKIDRzTtR2c6X2ecmv2FQWhvgNzdO4uqBVls",
            secretKey: "ELMOKLJKH8oGWcYHpCTfnu582obDj9Sj",
        },
        region: "ap-beijing",
        profile: {
            httpProfile: {
                endpoint: "iai.tencentcloudapi.com",
            },
        },
    };

    // 实例化要请求产品的client对象,clientProfile是可选的
    const client = new IaiClient(clientConfig);
    const params = {
        "GroupId": "123456",
        "PersonName": user.username,
        "PersonId": user._id.toString(),
        "Gender": 1,
        "Image": b64
    };
    client.CreatePerson(params).then(
        (data) => {
            console.log(data);
            res.send({
                code: 200,
                msg: '绑定成功！'
            })
        },
        (err) => {
            console.error("error", err);
            res.send({
                code: 401,
                msg: '绑定失败！'
            })
        }
    );
})



// 修改密码 
// 验证身份
router.post('/verifyCode', async (req, res) => {
    let { phone, code } = req.body
    let user = await userModel.findOne({ phone: phone })
    let phonecode = myCache.get("phonecodes");
    if (user && phonecode == code) {
        console.log(1111)
        res.send({
            code: 200,
            msg: '验证成功！',
            _id: user._id
        })
    } else {
        console.log(2222)
        res.send({
            code: 401,
            msg: '验证失败！'
        })
    }
})

router.post('/updatePsd', async (req, res) => {
    let { _id, password } = req.body
    const hashedPassword = await bcryptjs.hash(password, 10)
    await userModel.findByIdAndUpdate(_id, { password: hashedPassword })
    res.send({
        code: 200,
        msg: '修改成功！'
    })
})


// SSO验证中间件
const ssoMiddleware = (req, res, next) => {
    const token = req.headers.authorization?.split(' ')[1];
    if (!token) {
        token = req.cookies.sso_token;
    }
    if (token) {
        try {
            const decoded = jwt.verify(token, 'secretKey');
            req.user = decoded;
            next();
        } catch (error) {
            res.status(401).send('Invalid token');
        }
    } else {
        res.status(401).send('No token provided');
    }
};

// 获取用户信息路由（SSO相关）
router.get('/ssoUserinfo', ssoMiddleware, (req, res) => {
    res.json(req.user);
});

module.exports = router;
